package org.budo.graph.service.util;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.budo.graph.Constant;
import org.budo.support.freemarker.FreemarkerUtil;
import org.budo.support.java.net.util.JavaNetUtil;
import org.budo.support.lang.util.FileUtil;
import org.budo.support.lang.util.MapUtil;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.lang.util.ThreadUtil;
import org.budo.support.spring.io.util.ResourceUtil;
import org.springframework.context.ApplicationContext;

import com.alibaba.druid.support.json.JSONUtils;

/**
 * @author limingwei2
 */
public class SystemInfoUtil {
    private static final String DISK_SPACE_FM_PLACEHOLDER_HTM = Constant.GRAPH_TEMPLATE_PATH + "/system-info.htm";

    public static String writeSystemInfoResponse(ApplicationContext applicationContext, String url) {
        List<Map<String, Object>> diskSpaces = getDiskSpaceMap(applicationContext, url);

        Map<String, Object> map = MapUtil.stringObjectMap("diskSpaces", diskSpaces, //
                "ips", JavaNetUtil.getNetworkInterfaceAddresses(), //
                "memory", memory(), //
                "thread", thread());

        if (StringUtil.startsWith(url, "/system-info.json")) {
            return JSONUtils.toJSONString(map);
        }

        String inputString = ResourceUtil.classPathResourceInputStreamToString(DISK_SPACE_FM_PLACEHOLDER_HTM);
        return FreemarkerUtil.freemarkerRender(inputString, map);
    }

    private static Map<String, Object> thread() {
        Map<String, Object> map = new HashMap<String, Object>();
        ThreadGroup rootThreadGroup = ThreadUtil.getRootThreadGroup();
        map.put("totalThread", rootThreadGroup.activeCount());
        map.put("totalThreadGroup", rootThreadGroup.activeGroupCount());
        return map;
    }

    private static Map<String, Object> memory() {
        Map<String, Object> map = new HashMap<String, Object>();
        Runtime runtime = Runtime.getRuntime();
        map.put("totalMemory", runtime.totalMemory());
        map.put("maxMemory", runtime.maxMemory());
        map.put("freeMemory", runtime.freeMemory());
        return map;
    }

    private static List<Map<String, Object>> getDiskSpaceMap(ApplicationContext applicationContext, String url) {
        ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        File[] files = File.listRoots();
        for (File file : files) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("canonicalPath", FileUtil.getCanonicalPath(file));
            map.put("totalSpace", file.getTotalSpace());
            map.put("usableSpace", file.getUsableSpace());
            map.put("freeSpace", file.getFreeSpace());
            list.add(map);
        }
        return list;
    }
}